﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows;
using TorchView.GameContent.Data;
using System.Xml.Linq;
using TorchView.Imaging;
using System.Diagnostics;

namespace TorchView.GameContent.UI
{
  /// <summary>
  /// Class used to get item icons
  /// </summary>
  public static class Icons
  {
    private static Dictionary<string, Image> _Images = new Dictionary<string, Image>();

    static Icons()
    {
      LoadImages();
    }

    private static void LoadImages()
    {
      var imageSets = PakReader.GetFiles("media/UI/itemicons/", "*.imageset", System.IO.SearchOption.AllDirectories);
      using (DDSLoader loader = new DDSLoader())
      {
        foreach (var set in imageSets)
        {
          var stream = PakReader.OpenFile(set);
          var root = XElement.Load(stream, LoadOptions.None);
          string imageFile = GetAttributeValue(root, "Imagefile");
          var imageDDS = PakReader.OpenFile(imageFile);
          var masterImage = loader.Load(imageDDS);
          foreach (var i in root.Elements("Image"))
          {
            string name = GetAttributeValue(i, "Name");
            if (string.IsNullOrEmpty(name))
              continue;

            Int32Rect crop = new Int32Rect(GetAttributeValue(i, "XPos", 0),
              GetAttributeValue(i, "YPos", 0),
              GetAttributeValue(i, "Width", 0),
              GetAttributeValue(i, "Height", 0));

            _Images.Add(name, new Image(masterImage, crop));
          }
        }
      }
    }

    private static string GetAttributeValue(XElement element, string attributeName)
    {
      var attribute = element.Attribute(attributeName);
      if (attribute != null)
        return attribute.Value;
      return null;
    }

    private static int GetAttributeValue(XElement element, string attributeName, int defaultValue)
    {
      var attribute = element.Attribute(attributeName);
      if (attribute != null)
      {
        int value;
        if (int.TryParse(attribute.Value, out value))
          return value;
      }
      return defaultValue;
    }

    /// <summary>
    /// Get the image by the specified icon name
    /// </summary>
    /// <param name="iconName">Name of the image to retrieve</param>
    /// <returns>The image if one is found, null if one is not found</returns>
    public static BitmapSource GetImage(string iconName)
    {
      Image image;
      if (_Images.TryGetValue(iconName, out image))
        return image.GetImage();
      return null;
    }

    private class Image
    {
      private WeakReference _CurrentImage;
      private Int32Rect _CropArea;
      private BitmapSource _Master;

      public Image(BitmapSource master, Int32Rect cropArea)
      {
        _Master = master;
        _CropArea = cropArea;
      }

      public BitmapSource GetImage()
      {
        var currentImage = _CurrentImage == null ? null : _CurrentImage.Target as BitmapSource;
        if (currentImage != null)
          return currentImage;
        CroppedBitmap bitmap = new CroppedBitmap(_Master, _CropArea);
        bitmap.Freeze();
        _CurrentImage = new WeakReference(bitmap);
        return bitmap;
      }
    }
  }
}
